#include "bsp_usart.h"
#include <stdio.h>
#include <stdarg.h>
#include "string.h"
#include "gd32f3x0.h"

/* transmit buffer and receive buffer */
uint8_t tx_buffer[BUFFER_SIZE] = {0x00};
uint8_t rx_buffer[BUFFER_SIZE] = {0x00};
/* counter of transmit buffer and receive buffer */
__IO uint16_t tx_count = 0, rx_count = 0;
uint8_t recv_flag;
uint8_t send_flag;
uint16_t send_len;


/*!
    \brief      configure the USART0 GPIO ports
    \param[in]  none
    \param[out] none
    \retval     none
*/
void usart0_gpio_config(void)
{
    /* enable COM GPIO clock */
    rcu_periph_clock_enable(RCU_GPIOA);

    /* connect port to USARTx_Tx */
    gpio_af_set(GPIOA, GPIO_AF_1, GPIO_PIN_9);

    /* connect port to USARTx_Rx */
    gpio_af_set(GPIOA, GPIO_AF_1, GPIO_PIN_10);

    /* configure USART Tx as alternate function push-pull */
    gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_9);
    gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, GPIO_PIN_9);

    /* configure USART Rx as alternate function push-pull */
    gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_10);
    gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, GPIO_PIN_10);
}

void usart1_gpio_config(void)
{
    /* enable COM GPIO clock */
    rcu_periph_clock_enable(RCU_GPIOA);

    /* connect port to USARTx_Tx */
    gpio_af_set(GPIOA, GPIO_AF_1, GPIO_PIN_2);

    /* connect port to USARTx_Rx */
    gpio_af_set(GPIOA, GPIO_AF_1, GPIO_PIN_3);

    /* configure USART Tx as alternate function push-pull */
    gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_2);
    gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, GPIO_PIN_2);

    /* configure USART Rx as alternate function push-pull */
    gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_3);
    gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, GPIO_PIN_3);
}
/*!
    \brief      configure the USART0
    \param[in]  none
    \param[out] none
    \retval     none
*/
void usart0_config(void)
{
    /* enable USART clock */
    rcu_periph_clock_enable(RCU_USART0);

    /* USART configure */
    usart_deinit(USART0);
    usart_baudrate_set(USART0, 115200U);
    usart_receive_config(USART0, USART_RECEIVE_ENABLE);
    usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);

    usart_enable(USART0);
		nvic_irq_enable(USART0_IRQn, 0, 0);
}

void usart1_config(void)
{
    /* enable USART clock */
    rcu_periph_clock_enable(RCU_USART1);

    /* USART configure */
    usart_deinit(USART1);
    usart_baudrate_set(USART1, 115200U);
    usart_receive_config(USART1, USART_RECEIVE_ENABLE);
    usart_transmit_config(USART1, USART_TRANSMIT_ENABLE);

    usart_enable(USART1);
}


uint16_t usart_recv_data(uint8_t *buff, uint16_t buf_len)
{
	uint16_t ret = 0;
	recv_flag = 1;
	memset(rx_buffer,0x00,sizeof(rx_buffer));
	rx_count = 0;
	usart_interrupt_enable(USART0, USART_INT_RBNE);
	
	while(recv_flag);
	if(buff != NULL){
		if(rx_count > buf_len)
		{
			memcpy(buff, rx_buffer, buf_len);
		}
		else
		{
			memcpy(buff, rx_buffer, rx_count);
		}
	}
	
	return ret;
}

uint16_t usart_send_data(uint8_t *buff, uint16_t buf_len)
{
	uint16_t ret = 0;
	send_flag = 1;
	if(buff == NULL)
	{
		return ret;
	}
	memset(tx_buffer,0x00,sizeof(tx_buffer));
	tx_count = 0;
	memcpy(tx_buffer, buff, buf_len);
	send_len = buf_len;
	usart_interrupt_enable(USART0, USART_INT_TBE);
	while(send_flag);
	
	ret = tx_count;
	
	return ret;
}


